package com.angel.syncronization{

import flash.events.Event;
import flash.events.EventDispatcher;

import mx.controls.Alert;
import mx.rpc.AbstractOperation;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;

[Event(name="callSuccess", type="flash.events.Event")]

    public class BlockMethod {

        private static var METHOD_SUCCESS : String = 'METHOD_SUCCESS';

        private var _block : Block;
        private var _operation : AbstractOperation;
        private var _requisites : Array;

        private var _callbackFunction : Function;
        private var _callbackResult : Object;
        private var _operationResult : Object;

        private var _executed : Boolean = false;
        private var _success : Boolean = false;

    
        public function BlockMethod(operation : AbstractOperation, block : Block) {

            _operation = operation;
            _block = block;

            _operation.addEventListener(ResultEvent.RESULT, function(event : ResultEvent) : void {

                _operationResult = event.result;

                if(_callbackFunction != null) {

                    if(_operationResult != null) {
                        _callbackResult = _callbackFunction.call(null, _operationResult);
                    } else {
                        _callbackResult = _callbackFunction.call(null);
                    }

                }

                _success = true;
                _block.execute();

            });

            _operation.addEventListener(FaultEvent.FAULT, function (event : FaultEvent) : void {
                Alert.show('Se rompio' + event.message);
            });            

        }

        /**
         * Ejecuta la Operacion
         */
        public function execute() : void {

            // Si aun no fue invocada
            if(!_executed) {

                // La ejecuta si todos los metodos requeridos lo hicieron
                for each( var method : BlockMethod in _requisites ) {
                    if (!method.isSuccess) return;        
                }

                _executed = true;
                _operation.send();
                
            }
            
        }

        /**
         * Asigna un Callback a la Operacion, luego se guarda el resultado por si se necesita usar
         *
         * @param callbackFunction Function
         */
        public function callbackFunction(callbackFunction : Function) : BlockMethod {
            _callbackFunction = callbackFunction;
            return this;
        }

        /**
         * Asigna parametros a la Operacion
         */
        public function arguments(... args:Array) : BlockMethod {
            _operation.arguments = args;
            return this;
        }

        /**
         * Asigna una lista de ServiceMethod que deben finalizar para poder ejecutar
         */
        public function requisites(... args:Array) : BlockMethod {
            _requisites = args;
            return this;
        }

        /**
         * Retorna el resultado de la CallBackFunction
         */
        public function get callbackResult() : Object {
            return _callbackResult;
        }

        /**
         * Retorna el resultado de la Operacion
         */
        public function get operationResult() : Object {
            return _operationResult;
        }

        /**
         * Pregunta si la Operacion ya ha sido ejecutada (no necesariamente termino de ejecutar)
         */
        public function get isExecuted() : Boolean {
            return _executed;
        }

        /**
         * Pregunta si la Operacion ya ha finalizado
         */
        public function get isSuccess() : Boolean {
            return _success;
        }

    }



}